import redis
from django.conf import settings
import pickle
import time
from datetime import datetime
import pytz
from detection.models import RealtimeDetectionResult, RealtimeMonitoring
from collections import defaultdict
import json
from django.utils import timezone
import logging

# 配置日志
logger = logging.getLogger(__name__)

# Redis连接
redis_client = redis.Redis(
    host=settings.CACHES['default']['LOCATION'].split('//')[1].split(':')[0],
    port=int(settings.CACHES['default']['LOCATION'].split(':')[2].split('/')[0]),
    db=1,
    decode_responses=False
)

def process_session_data(session_id, is_final=False):
    """
    处理会话数据，将连续的检测结果合并
    每5分钟处理一次数据，或者在会话结束时处理
    """
    try:
        # 获取会话信息，使用session_id字段
        session = RealtimeMonitoring.objects.get(session_id=session_id)
        logger.info(f"开始处理会话 {session_id} 的数据")
        
        # 获取所有帧ID
        session_key = f"detection:session:{session.id}"  # 使用主键id作为Redis键
        frame_ids = redis_client.hkeys(session_key)
        if not frame_ids:
            logger.info(f"会话 {session_id} 没有检测数据")
            return

        # 按时间戳排序
        frame_ids.sort()
        logger.info(f"会话 {session_id} 共有 {len(frame_ids)} 帧数据需要处理")
        
        # 用于跟踪每个类别的检测
        class_tracking = {}  # {class_id: {start_time, end_time, class_name, max_confidence}}
        
        for frame_id in frame_ids:
            frame_data = redis_client.hget(session_key, frame_id)
            if not frame_data:
                continue
                
            try:
                frame_data = pickle.loads(frame_data)
                timestamp = frame_data.get('timestamp', time.time())
                
                # 处理每个检测结果
                for detection in frame_data.get('detections', []):
                    class_id = detection['class_id']
                    class_name = detection['class_name']
                    confidence = detection['confidence']
                    
                    # 如果是新的类别或与上次检测间隔超过1秒
                    if (class_id not in class_tracking or 
                        timestamp - class_tracking[class_id]['end_time'] > 1):
                        
                        # 如果之前有未保存的检测，先保存
                        if class_id in class_tracking:
                            prev_detection = class_tracking[class_id]
                            RealtimeDetectionResult.objects.create(
                                session=session,
                                class_id=class_id,
                                class_name=prev_detection['class_name'],
                                start_time=prev_detection['start_time'],
                                end_time=prev_detection['end_time'],
                                confidence=prev_detection['max_confidence']
                            )
                        
                        # 开始新的检测记录
                        class_tracking[class_id] = {
                            'start_time': timestamp,
                            'end_time': timestamp,
                            'class_name': class_name,
                            'max_confidence': confidence
                        }
                    else:
                        # 更新现有检测记录
                        class_tracking[class_id]['end_time'] = timestamp
                        class_tracking[class_id]['max_confidence'] = max(
                            class_tracking[class_id]['max_confidence'],
                            confidence
                        )
            except Exception as e:
                logger.error(f"处理帧 {frame_id} 数据时出错: {str(e)}", exc_info=True)
                continue

        for class_id, detection in class_tracking.items():
            start_time = timezone.make_aware(datetime.fromtimestamp(detection['start_time']))
            end_time = timezone.make_aware(datetime.fromtimestamp(detection['end_time']))
            
            RealtimeDetectionResult.objects.create(
                session=session,
                class_id=class_id,
                class_name=detection['class_name'],
                start_time=start_time.timestamp(),
                end_time=end_time.timestamp(),
                confidence=detection['max_confidence']
            )
        
        # 清理Redis数据
        if is_final:
            # 如果是最终处理，删除所有相关数据
            redis_client.delete(session_key)
            logger.info(f"会话 {session_id} 已结束，所有数据已保存到数据库")
        else:
            # 如果不是最终处理，只删除已处理的帧
            for frame_id in frame_ids:
                redis_client.hdel(session_key, frame_id)
            logger.info(f"会话 {session_id} 数据已处理，等待下次处理")
        
    except RealtimeMonitoring.DoesNotExist:
        logger.error(f"会话 {session_id} 不存在")
    except Exception as e:
        logger.error(f"处理会话数据时出错: {str(e)}", exc_info=True)

    except Exception as e:
        print(f"Error in process_session_data: {str(e)}")
        import traceback
        print(traceback.format_exc()) 